#include "ADC.h"

void init_ADC() {
	// Set the reference voltage used for conversation to AVCC (5V).
	// The sampled analog signal is not allowed to be higher as the reference voltage.
	// The converted values are related to the interval [0-5]. The highest value (1023) for a measured analogous signal of 5V and the
	// lowest value (0) for 0V.
	ADMUX = (1 << REFS0);
	
	// We use 64 as a prescale factor. The work frequency of the ADC is F_CLK/64.
	ADCSRA = (1 << ADPS2 | 1 << ADPS1 | 1 << ADEN);
	
	// At first start up a sample conversation is needed, which we are doing here
	uint16_t sample;
	ADCSRA |= (1 << ADSC);
	
	while(ADCSRA & (1 << ADSC)) {
		; // Wait till the conversation is complete
	}

	// Read the conversation value
	sample = ADC;
}

uint16_t read_ADC(uint8_t channel)
{
	// Set the specified channel as the input for the ADC
	ADMUX = (ADMUX & ~(0x1F)) | (channel & 0x1F);
	// Start conversation
	ADCSRA |= (1<<ADSC);         
	while (ADCSRA & (1<<ADSC)) {
		; // Wait for the result of the conversation
	}  

	return ADC;
}

uint16_t read_2_ADC(uint8_t channel)
{
	uint32_t sum = 0;
	
	// Take two samples and add them
	for (uint8_t i = 0; i < 2; i++ ) {
		sum += read_ADC(channel);
	}
	
	// Divide the sum by two and return the result
	return (uint16_t)(sum >> 1);
}

uint16_t read_4_ADC(uint8_t channel)
{
	uint32_t sum = 0;
	
	// Take four samples and add them
	for (uint8_t i = 0; i < 4; i++ ) {
		sum += read_ADC(channel);
	}
	
	// Divide the sum by four and return the result
	return (uint16_t)(sum >> 2);
}


